package user

import (
	"container/list"
	"errors"
	"gitee.com/cooge/impush/message"
	"gitee.com/cooge/impush/util"
	"net"
	"sync"
	"time"
)

type User struct {
	*Linklist
	addTime *time.Time
	UserId string
}

func NewUser(userId string) *User {
	return &User{&Linklist{List: list.New(), lock: new(sync.RWMutex)}, util.GetNowTime(),userId}
}
func (u *User) SendMessage(msg *message.Message) (int, error) {
	for _, v := range u.GetAllArray() {
		num, err := v.SendMessage(msg)
		if err == nil {
			return num, nil
		}
	}
	return 0, errors.New(message.NO_USER)
}
func (u *User) SendLocalMessage(msg *message.Message) (int, error) {
	for _, v := range u.GetAllArray() {
		if v.IsLocal() {
			num, err := v.SendMessage(msg)
			if err == nil {
				return num, nil
			}
		}
	}
	return 0, errors.New(message.NO_USER)
}

func (u *User) GetCreateTime() *time.Time {
	return u.addTime
}
func (u *User) GetUserConns() []UserConn {
	return u.GetAllArray()
}

type UserConn interface {
	SendMessage(*message.Message) (int, error)
	Close(userId string) error
	GetAddress() string
	IsLocal() bool
	GetType() string
	GetCreateTime() *time.Time
	GetUserId() string
}

type UserTCPConn interface {
	Close() error
	RemoteAddr() net.Addr
	Write([]byte) (int, error)
	Read([]byte) (int, error)
	SetReadDeadline(time.Time) error
	SetDeadline(time.Time) error
}

type UserLite struct {
	UserTCPConn
	LiveTime   int
	UserId     string
	CreateTime *time.Time
	Type string
	Local bool
}

func NewUserLite(conn UserTCPConn, LiveTime int, UserId string, CreateTime *time.Time,Type string,islocal bool) *UserLite {
	return &UserLite{UserTCPConn: conn, LiveTime: LiveTime, UserId: UserId, CreateTime: CreateTime,Type:Type,Local:islocal}
}

func (tcp *UserLite) GetType() string {
	return tcp.Type
}

func (tcp *UserLite) IsLocal() bool {
	return tcp.Local
}

func (ul *UserLite) GetAddress() string {
	return ul.RemoteAddr().String()
}
func (ul *UserLite) GetCreateTime() *time.Time {
	return ul.CreateTime
}
func (ul *UserLite) GetUserId() string {
	return ul.UserId
}

/**
	用户缓存
**/
var userMap UserExMap

func init() {
	userMap = NewUserExMap()
}

func AddUser(key string, value UserConn) bool {
	return userMap.Add(key, value)
}


func AddM(key string, value interface{}) bool {
	return userMap.AddM(key, value)
}
func GetDelMS(key string)[]interface{}  {
	return userMap.GetDelMS(key)
}

func DeleteUser(key string, value UserConn) (bool, *time.Time) {
	return userMap.Delete(key, value)
}

func DeleteOUser(key string, value UserConn) {
	userMap.DeleteOvalue(key, value)
}

func DeleteValue(value UserConn) {
	userMap.DeleteValue(value)
}

func DeleteKey(key string) {
	userMap.DeleteKey(key)
}

func GetSetOneUser(key string, value UserConn) (UserConn, bool) {
	return userMap.GetSetOneValue(key, value)
}

func GetUser(key string) *User {
	return userMap.Get(key)
}

func GetUserAddtime(key string) *time.Time {
	return userMap.GetAddTime(key)
}

func GetLen(key string) int {
	return userMap.Len(key)
}
func AllLen() int {
	return userMap.AllLen()
}
func GetKeyArray(start int, num int) []string {
	return userMap.GetKeyArray(start, num)
}
func GetValueArray(start int, num int) []*User {
	return userMap.GetValueArray(start,num)
}

func GetALlKeyArray() []string {
	return userMap.GetALLKey()
}
